package cn.sicnu.cs.employment.rest;

import cn.sicnu.cs.employment.common.ResultInfo;
import cn.sicnu.cs.employment.common.ResultInfoUtil;
import cn.sicnu.cs.employment.common.util.BeanConvertUtils;
import cn.sicnu.cs.employment.domain.entity.*;
import cn.sicnu.cs.employment.domain.vo.BackgroundCommentVo;
import cn.sicnu.cs.employment.domain.vo.BgAppealVo;
import cn.sicnu.cs.employment.domain.vo.EmployeeExpProjectVo;
import cn.sicnu.cs.employment.domain.vo.EmployeeInfoVo;
import cn.sicnu.cs.employment.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.*;

import static cn.sicnu.cs.employment.common.Constants.*;
import static cn.sicnu.cs.employment.common.util.RequestUtil.getCurrentUrl;
import static cn.sicnu.cs.employment.common.util.RequestUtil.getCurrentUser;

@Slf4j
@RestController
@RequestMapping("/emp")
@RequiredArgsConstructor
public class EmployeeResource {
    private final IEmployeeService employeeService;
    private final IUploadService uploadService;
    private final IBgAppealService appealService;
    private final IAdminRoleService adminService;
    private final ICompanyService companyService;
    private final IBackgroundCommentService commentService;


    @GetMapping("/resume")
    public ResultInfo<EmployeeInfoVo> getUserResume(@RequestParam(value = "id", required = false) Long id) {
        if (id == null) {
            id = employeeService.getCurrentEmpId();
        }
        val employee = employeeService.getUserInfoById(id);
        EmployeeInfoVo employeeVo = BeanConvertUtils.toEmpVo(employee);
        return ResultInfoUtil.buildSuccess(getCurrentUrl(), employeeVo);
    }

    @PostMapping("/info")
    public ResultInfo<Void> updateUserInfo(@RequestBody Map<String, String> info) {

        employeeService.updateEmpInfo(
                EmployeeInfo.builder()
                .id(employeeService.getCurrentEmpId())
                .gender(info.get("sex"))
                .birthDay(info.get("birth"))
                .identity(info.get("identity"))
                .major(info.get("major"))
                .degree(info.get("degree"))
                .advantage(info.get("advantage"))
                .build()
        );
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 获取员工的个人背调信息
     */
    @GetMapping("/info")
    public ResultInfo<EmployeeInfoVo> getUserInfo(@RequestParam(value = "id", required = false) Long id) {
        if (id == null) {
            id = employeeService.getCurrentEmpId();
        }
        val employee = employeeService.getUserInfoById(id);
        EmployeeInfoVo employeeVo = BeanConvertUtils.toEmpVo(employee);
        Set<EmployeeCompany> allEmpComByEmpId = employeeService.getAllEmpComByEmpId(employee.getId());
        Set<EmployeeExpProjectVo> projectVos = new HashSet<>();
        for (EmployeeCompany empCom : allEmpComByEmpId) {
            Set<EmployeeExpProject> projectExp = employeeService.getProjectExp(employee.getId(), empCom.getComId());
            CompanyInfo comInfo = companyService.getCompanyInfo(empCom.getComId());
            projectVos.add(
                    EmployeeExpProjectVo.builder()
                            .startTime(empCom.getInTime())
                            .endTime(empCom.getOffTime())
                            .industry(comInfo.getIndustry())
                            .companyName(comInfo.getComName())
                            .positionArea(empCom.getPositionArea())
                            .positionDepartment(empCom.getPositionDepartment())
                            .positionName(empCom.getPosition())
                            .positionRelation(empCom.getPositionRelation())
                            .salary(empCom.getSalary())
                            .character(comInfo.getComCharacter())
                            .work(projectExp)
                            .build()
            );
        }
        //补充教育经历、实习经历、项目经历
        EmployeeInfoVo employeeVoToSend = employeeVo
                .withEducationExperience(BeanConvertUtils.toEmpExpEdu(employeeService.getEducationExp(employee.getId())))
                .withPersonExperience(BeanConvertUtils.toEmpExpIntern(employeeService.getInternshipExp(employee.getId())))
                .withProjectExperience(projectVos);
        return ResultInfoUtil.buildSuccess(getCurrentUrl(), employeeVoToSend);
    }

    @GetMapping("/comment")
    public ResultInfo<EmployeeInfoVo> getAllEmpComments(@RequestParam(value = "id", required = false) Long id) {
        if (id == null) {
            id = employeeService.getCurrentEmpId();
        }
        EmployeeInfo employee = employeeService.getUserInfoById(id);
        EmployeeInfoVo employeeVo = BeanConvertUtils.toEmpVo(employee);
        Set<EmployeeCompany> allEmpComByEmpId = employeeService.getAllEmpComByEmpId(employee.getId());
        Set<BackgroundCommentVo> comments = new HashSet<>();
        for (EmployeeCompany empCom : allEmpComByEmpId) {
            Set<BackgroundComment> comment = commentService.getComments(empCom.getEmpId(), empCom.getComId());
            CompanyInfo comInfo = companyService.getCompanyInfo(empCom.getComId());
            comments.add(
                    BackgroundCommentVo.builder()
                            .startTime(empCom.getInTime())
                            .endTime(empCom.getOffTime())
                            .industry(comInfo.getIndustry())
                            .companyName(comInfo.getComName())
                            .positionArea(empCom.getPositionArea())
                            .positionDepartment(empCom.getPositionDepartment())
                            .positionName(empCom.getPosition())
                            .positionRelation(empCom.getPositionRelation())
                            .salary(empCom.getSalary())
                            .character(comInfo.getComCharacter())
                            .comments(comment)
                            .build()
            );
        }
        employeeVo.setComments(comments);
        return ResultInfoUtil.buildSuccess(getCurrentUrl(), employeeVo);
    }

    /**
     * 添加或修改头像
     */
    @PostMapping("/img")
    public ResultInfo<Void> addHeadImg(@RequestParam("img") MultipartFile file) {
        if (file.isEmpty()) {
            return ResultInfoUtil.buildError(INPUT_EMPTY, "上传文件为空", getCurrentUrl());
        }
        try {
            FileInputStream fileIn = (FileInputStream) file.getInputStream();
            // 用来获取其他参数
            String fileSaveName = PREFIX_HEAD_IMG + getCurrentUser().getUsername();
            String path = uploadService.uploadImg(fileIn, fileSaveName);
            employeeService.updateHeadImg(getCurrentUser().getId(), path);
            log.info("保存的图片地址={}", path);
        } catch (Exception e) {
            return ResultInfoUtil.buildError(OTHER_ERROR, "上传出错了！" + e.getMessage(), getCurrentUrl());
        }
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 获取头像链接
     */
    @GetMapping("/img")
    public ResultInfo<String> getHeadImg() {
        Long id = getCurrentUser().getId();
        String headImg = employeeService.getHeadImg(id);
        if ("".equals(headImg)) {
            return ResultInfoUtil.buildError(SAVED_ERROR, "用户暂未设置头像！", getCurrentUrl());
        }
        return ResultInfoUtil.buildSuccess(getCurrentUrl(), PREFIX_PIC_STORE + headImg);
    }

    /**
     * 保存申诉信息
     */
    @PostMapping("/appeal")
    public ResultInfo<Void> addAppeal(@RequestBody Map<String, String> infos) {
        Integer type = null;
        try {
            type = Integer.valueOf(infos.get("type"));
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Long expId = null;
        try {
            expId = Long.valueOf(infos.get("expProId"));
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        BgAppeal appealToSave = BgAppeal.builder()
                .expProId(expId)
                .empId(employeeService.getCurrentEmpId())
                .type(type)
//                .status(appeal.getStatus())
                .title(infos.get("title"))
                .content(infos.get("content"))
                .time(dateFormat.format(new Date()))
                .build();
        EmployeeExpProject expToSave = EmployeeExpProject.builder()
                    .comId(employeeService.findComIdByEmpId(employeeService.getCurrentEmpId()))
                    .project(infos.get("project"))
                    .description(infos.get("description"))
                    .time(infos.get("time"))
                    .content(infos.get("proContent"))
                    .position(infos.get("position"))
                    .isAppeal(1)
                    .build();
        appealService.saveAppeal(appealToSave, expToSave);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 更新申诉/申请的信息
     */
    @PutMapping("/appeal")
    @Deprecated
    public ResultInfo<Void> updateAppeal(@RequestBody @Valid BgAppealVo appealVo) {
        if (!appealService.isAppealAvailable(appealVo.getId())) {
            return ResultInfoUtil.buildError(ERROR_CODE, "不能对已经发送的申诉/申请做修改", getCurrentUrl());
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        BgAppeal appealToUpdate = BgAppeal.builder()
                .id(appealVo.getId())
                .content(appealVo.getContent())
                .time(dateFormat.format(new Date()))
                .build();
//        appealService.saveAppeal(appealToUpdate);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 发送申诉
     */
    @PostMapping("/appeal/send")
    @Deprecated
    public ResultInfo<Void> sendAppeal(@RequestParam("id") Long appealId) {
        appealService.sendAppeal(appealId);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 删除未发送的申诉
     */
    @DeleteMapping("/appeal/{id}")
    public ResultInfo<Void> deleteAppeal(@RequestParam("id") Long appealId) {
        if (!appealService.isAppealAvailable(appealId)) {
            return ResultInfoUtil.buildError(ERROR_CODE, "该条申诉已经发送，无法删除", getCurrentUrl());
        }
        appealService.deleteAppeal(appealId);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    /**
     * 获取当前的所有申诉信息
     */
//    @GetMapping("/appeal")
//    public ResultInfo<List<BgAppealVo>> getAppeals(@RequestParam(value = "type", required = false) Integer type,
//                                                   @RequestParam(value = "status", required = false) Integer status,
//                                                   @RequestParam(value = "start", required = false) String start,
//                                                   @RequestParam(value = "end", required = false) String end) {
    @PostMapping("/appeals")
    public ResultInfo<List<BgAppealVo>> getAppeals(@RequestBody Map<String, String> infos){
        Integer type = null;
        try {
            type = Integer.valueOf(infos.get("type"));
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
        Integer status = null;
        try {
            status = Integer.valueOf(infos.get("status"));
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        String start = infos.get("start");
        String end = infos.get("end");
        List<BgAppeal> appeals = appealService.getAllAppealsByEmpId(
                employeeService.getCurrentEmpId(), type, status, start, end);
        List<BgAppealVo> appealVos = new LinkedList<>();
        // 补充项目信息相关
        for (BgAppeal appeal : appeals) {
            appealVos.add(
                    BeanConvertUtils.toBgAppeal(appeal,
                            employeeService.getProjectExpById(appeal.getExpProId()),
                            adminService.getInfo(appeal.getRespId())
                    )
            );
        }

        return ResultInfoUtil.buildSuccess(getCurrentUrl(), appealVos);
    }

    @PostMapping("/comment/self")
    public ResultInfo<Void> addSelfComments(@RequestBody Map<String, String> info) {
        String content = info.get("content");

        Long id = null;
        try {
            id = Long.valueOf(info.get("id"));
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
        commentService.addSelfComment(content, id);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

    @PostMapping("/info/self")
    public ResultInfo<Void> addSelfBackInfoComments(@RequestBody Map<String, String> info){
        String content = info.get("content");
        Long id = null;
        try {
            id = Long.valueOf(info.get("id"));
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        employeeService.addBackExpSelf(content, id);
        return ResultInfoUtil.buildSuccess(getCurrentUrl());
    }

}